package com.dodoke.service.impl;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimerTask;

import com.alibaba.fastjson.JSONObject;
import com.dodoke.common.config.DodokeConfig;
import com.dodoke.common.config.ServerConfig;
import com.dodoke.common.constant.Constants;
import com.dodoke.common.constant.HttpStatus;
import com.dodoke.common.utils.file.FileUploadUtils;
import com.dodoke.common.utils.file.FileUtils;
import com.dodoke.common.utils.http.HttpUtils;
import com.dodoke.domain.WxDetailQr;
import com.dodoke.framework.manager.AsyncManager;
import com.dodoke.mapper.WxDetailQrMapper;
import com.dodoke.service.IWxDetailQrService;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

/**
 * 【二维码】Service业务层处理
 * 
 * @author dodoke
 * @date 2020-08-25
 */
@Service
public class WxDetailQrServiceImpl implements IWxDetailQrService
{
    @Autowired
    private WxDetailQrMapper wxDetailQrMapper;

    @Autowired
    private ServerConfig serverConfig;

    /***
     * 根据id查询二维码图片
     * @param id
     * @return
     */
    @Override
    public WxDetailQr selectWxDetailQrById(Long id)
    {
        return wxDetailQrMapper.selectWxDetailQrById(id);
    }

    /***
     * 查询二维码编号对应的商品id
     * @param groupNum 二维码编号（组号）
     * @return
     */
    @Override
    public List<Integer> selectQrGoodsIds(Long groupNum) {
        return wxDetailQrMapper.selectQrGoodsIds(groupNum);
    }

    /**
     * 查询【请填写功能名称】列表
     * 
     * @param wxDetailQr 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    @Override
    public List<WxDetailQr> selectWxDetailQrList(WxDetailQr wxDetailQr)
    {
        return wxDetailQrMapper.selectWxDetailQrList(wxDetailQr);
    }

    /**
     * 新增【二维码】
     * 分成四个步骤
     * 1. 向微信小程序接口发起get请求，获取accessToken
     * 2. 解析返回的json数据包，获取accessToken，将其作为请求参数再向另一个接口
     *      发起请求，获得小程序码
     * 3. 拿到小程序码，用输出流保存至本地
     * 4，将小程序码对应的网络路径保存至数据库，用于后续前端页面请求时的显示
     * @param code 同一编码值的二维码对应同一数据源
     */
    @Override
    public int insertWxDetailQr(String code){
        // 先获取accseeToken
        String accsessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("grant_type=")
                .append("client_credential&")
                .append("appid=")
                .append(Constants.APP_ID)
                .append("&")
                .append("secret=")
                .append(Constants.SECRET);
        String res = HttpUtils.sendGet(accsessTokenUrl, stringBuilder.toString());
        JSONObject jsonObject = JSONObject.parseObject(res);
        // 到这一步获取到了accseeToken
        String access_token = jsonObject.getString("access_token");
        String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+access_token;
        Map<String,Object> map = new HashMap<>(16);
        map.put("scene",code);
        // 构建好url路径、需要post的参数，然后发起请求，这一步拿到了小程序码然后保存到了本地，返回保存的文件名
        String filename = HttpUtils.sendPost4Qr(url,JSONObject.toJSONString(map));
        String projectUrl = serverConfig.wholeProjectUrl();
        // 构建http形式的访问路径，用于页面显示该二维码，将此路径保存至数据库
        String httpPath = serverConfig.getContextPath().equals("/")?
                projectUrl.substring(0,projectUrl.length()-1)+Constants.RESOURCE_PREFIX+"/"+filename
                :projectUrl+Constants.RESOURCE_PREFIX+"/"+filename;
        WxDetailQr wxDetailQr = new WxDetailQr();
        wxDetailQr.setCode(code);
        wxDetailQr.setImageUrl(httpPath);
        return wxDetailQrMapper.insertWxDetailQr(wxDetailQr);
    }


    /**
     * 删除二维码
     * @param id
     * @return
     */
    @Override
    public int deleteWxDetailQrById(Long id) {
        String imageUrl = wxDetailQrMapper.selectWxDetailQrById(id).getImageUrl();
        int affectNum = wxDetailQrMapper.deleteWxDetailQrById(id);
        AsyncManager me = AsyncManager.me();
        me.execute(new TimerTask() {
            @Override
            public void run() {
                // 异步将本地磁盘上的图片资源也删除
                StringBuilder stringBuilder = new StringBuilder();
                // 项目的路径长度
                String servletPath = serverConfig.getContextPath().equals("/")?"":serverConfig.getContextPath();
                int index = stringBuilder.append(Constants.HTTP)
                        .append(ServerConfig.getIP())
                        .append(":")
                        .append(serverConfig.getPort())
                        .append(servletPath).toString().length();
                String filename = DodokeConfig.getProfile() + imageUrl.substring(index + Constants.RESOURCE_PREFIX.length());
                FileUtils.deleteFile(filename);
            }
        });
        return affectNum;
    }

}
